home *** CD-ROM | disk | FTP | other *** search
- /* BeepShuffle.c */
- /* BeepShuffle © 1990, by Alex Chaffee
- chaffee@reed.uucp CIS:71210,1117
- Reed College Box 259, Portland OR 97202
-
- This source may be freely distributed.
-
- Version Date History
- 0.1 7/21/89 Version 1
- 0.2 1/9/90 Legalized tail-patch
- Implemented true randomness (using Ticks instead of Random)
- 0.3 1/25 HPurge() and if (H)
-
- /* An INIT that will patch SysBeep to select
- a random beep from all installed 'snd 's.
- Custom Headers: ON
- */
-
- /* low-mem globals */
- #define SYSBEEP 0xA9C8 /* SysBeep Trap# */
- #define SndPlayTrap 0x05 /* SndPlay Trap# */
- #define UnTrap 0x9F /* Unimplemented Trap # */
-
- extern unsigned char SoundActive: 0x027E; /* Is an async sound already playing? */
- extern unsigned char SdVolume: 0x0260; /* volume */
-
- /* program globals/constants */
- #define int_HIBITOFF 0x7FFF
- static long OldSysBeep; /* Former SysBeep trap address */
- #define SUCCESS 128 /* ICN# codes */
- #define FAIL 129
-
- /* forward declarations */
- extern pascal void mySysBeep();
- extern main();
- pascal void ShowINIT(short iconID, short moveX);
-
- main()
- {
- register Handle H;
- short theIcn;
-
- /* save all system registers */
- asm {
- movem.l a1-a5/d0-d7, -(SP)
-
- /* Set Up A4 to point to top of resource to access global variables */
-
- LEA main, A4 ; put top address in A4
-
- /* Self-preservation */
-
- LEA main, A0 ; put address of resource in parameter
- _RecoverHandle
- move.l a0, H ; who am i?
- }
- HLock(H);
- DetachResource(H);
-
- /* Check for compatibility */
-
- /* check to see if SndPlay is implemented as per TN#156. */
- if ( NGetTrapAddress(SndPlayTrap, ToolTrap) ==
- NGetTrapAddress(UnTrap, ToolTrap) )
- { /* failure */
- theIcn = FAIL;
- }
-
- /* Install my beep */
- else if (Button()) /* Startup click -> Failure */
- theIcn = FAIL;
- else {
- OldSysBeep = GetTrapAddress(SYSBEEP);
- SetTrapAddress(&mySysBeep, SYSBEEP);
- theIcn = SUCCESS;
- }
- ShowINIT(theIcn, -1);
-
- asm {
- movem.l (SP)+, a1-a5/d0-d7 ; restore registers
- }
- }
-
- pascal void mySysBeep(duration)
- int duration;
- {
- register int total;
- register int i;
- register Handle H;
-
- /* since this is a trap routine, we must preserve the registers */
- asm {
- movem.l a1-a5/d0-d7, -(SP) ; a6 is lunk, a7 is SP
- /* set up globals */
- LEA main, A4 ; set up globals
- }
-
- if (!SoundActive && SdVolume)
- { /* Find snd */
- total = CountResources('snd ');
- if (total)
- {
- i = ((int)Ticks & int_HIBITOFF) % total + 1; /* non-neg., 1 -> total */
- H = GetIndResource('snd ', i);
- if (H) {
- SndPlay(0L, H, FALSE); /* should I error-check? Nah… */
- HPurge(H); /* make sure it's cleaned up */
- asm { /* return NOW! */
- movem.l (SP)+, a1-a5/d0-d7 ; restore registers
- UNLK A6 ; remove stack frame
- movea.l (SP)+, A0 ; get return addr
- addq.w #2, SP ; pop parameter
- JMP (A0) ; return
- }
- }
- }
- }
- asm { /* else legally jump to real SysBeep */
- movea.l OldSysBeep, A0 ; get jump addr
- movem.l (SP)+, a1-a5/d0-d7 ; restore registers
- UNLK A6 ; remove stack frame
- JMP (A0) ; jump
- }
- }
-